package main

import (
	"context"
	"fmt"
	"time"
)

func f2() {
	// 父级context, 超时时间: 1000ms
	parentCtx, cancel1 := context.WithTimeout(context.TODO(), 1000*time.Millisecond)
	defer cancel1()
	t0 := time.Now()

	time.Sleep(500 * time.Millisecond)
	// 子级context, 超时时间: 1000ms
	childCtx, cancel2 := context.WithTimeout(parentCtx, 100*time.Millisecond)
	defer cancel2()
	t1 := time.Now()

	// 验证父子级别的context管道中，以谁的时间为准：以所有链上最短的时间为准
	select {
	case <-childCtx.Done():
		err := childCtx.Err()
		t3 := time.Now()
		fmt.Println("t3到t0的间隔时间:", t3.Sub(t0).Milliseconds()) // 602
		fmt.Println("t3到t1的间隔时间:", t3.Sub(t1).Milliseconds()) // 101
		fmt.Println("err:", err)                              // err: context deadline exceeded
		/**
		这是因为childCtx的timeout=100ms, 而他的父亲parentCtx的timeout=1000ms，但是因为中间sleep了500ms
		则在执行过程中，childCtx执行完成后，话费101ms，sleep了500ms之后，紧接着对应的parentCtx也被强制关闭
		所以t3到t1的间隔时间为childCtx实际花费的时间101ms, t3到t0的间隔时间 约等于: (101 + 500)ms
		*/
	}
}
